/*
 * @Author: lei
 * @Description: 生产者消费者模型示例
 * @FilePath: \code\producer_consumer.cc
 */

#include <mutex>
#include <condition_variable>
#include <thread>
#include <functional>
#include <vector>
#include <iostream>


using namespace std;

using Functor = std::function<void(void)>;

mutex mtx;
condition_variable cond;

vector<Functor> shared_vec;

void func(int i )
{
	cout << "第 " << i << "次打印 in thread: " << std::this_thread::get_id() << endl;
}
void Producer()
{
	//加锁，放东西到shared_vec，解锁；
	//TODO:
	int i = 1;
	while(1)
	{
		Functor f = std::bind(func,i++);
		{
			unique_lock<mutex> lk(mtx);
			shared_vec.push_back(f);
		}
		cond.notify_one();
		//std::this_thread::yield()与std::this_thread::sleep_for()、std::this_thread::sleep_until()
		std::this_thread::sleep_for(std::chrono_literals::500ms);
		//sleep(1);
		//
	}

}
void Consumer()
{
	vector<Functor> temp_vec;
	while(1)
	{
		{
			unique_lock<mutex> lk(mtx);
			while(shared_vec.empty())
				cond.wait(lk);
		}
		temp_vec.swap(shared_vec);
		for(auto& t : shared_vec)
		{
			t();
		}
	}
}

int main()
{
	std::vector<std::thread> thread_vec;
	thread_vec.push_back(std::move(std::thread(&Producer)));
	thread_vec.push_back(std::move(std::thread(&Producer)));
	thread_vec.push_back(std::move(std::thread(&Producer)));
	thread_vec.push_back(std::move(std::thread(&Consumer)));
	return 0;
}
